/**
 * @class   wosh::services::BuildingManagerBundle
 * @brief   Manager of Building Objects (such as Floor, Room and other
 *          types from wosh::building namespace).
 *
 *
 locations planning:
------------------------------------------------------------------
 goals:
 - used to reference users' position
 - someway mapped to BuildingObject
 - hierarchy, cross-relations (access-to, child-of)
 - geometry and distance
 - 

 system-relations
 - WRITTEN: by BuildingManager only
 - READ: heavily by BigBrother (predict, undestand where users are)
 - READ: my Butler.. to predict and choose users' actions
 - REFERRED: saved in Users' data (through UserManager)

------------------------------------------------------------------
 *
 *
 * @ingroup Services
 ****************************************************************************
 * @version $Id: BuildingManagerBundle.h 2887 2010-08-11 08:09:41Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Bundles_Services_BuildingManager_H__
 #define __WOSH_Bundles_Services_BuildingManager_H__

 #include <core/BundleGeneric.h>
 #include <core/Containers.h>

 #include <framework/building/BuildingObject.h>
 #include <framework/building/Location.h>

 #include <interfaces/Service.h>
 #include <interfaces/services/BuildingManager.h>


using namespace wosh::building;
namespace wosh {
 namespace services {

 #define _BuildingManager_VERSION				0.85


class BuildingManagerBundle :	public BundleGeneric,
								public virtual wosh::interfaces::services::BuildingManager
 {
	WOSH_BUNDLE(wosh::services::BuildingManagerBundle)
	WOSH_BUNDLE_INTERFACE("wosh::interfaces::services::BuildingManager")
	WOSH_BUNDLE_SINGLETON(1,0)

	typedef MapT<std::string, BuildingObject*> tStrBuildingObjectMap;
	typedef MapT<std::string, Location*> tStrLocationMap;


	public:
		BuildingManagerBundle();
		virtual ~BuildingManagerBundle();


	public:
		WRESULT bundleStart();
		WRESULT bundleStop();

		void busMessage( const Message& message, const Bus* source );

//@}
/** @name BuildingManager Interface
 * @{
 ******************************************************************************/
	public:
		WRESULT loadBuildingObjects();
		WRESULT saveBuildingObjects();
//@}
/** @name IPropertiesProviderListener interface
 * @{
 ******************************************************************************/
 	public:
//@}
/** @name Internal methods
 * @{
 ******************************************************************************/
	protected:
		WRESULT addObject_( BuildingObject* obj );
		WRESULT removeObject_( BuildingObject* obj );

		WRESULT fixReferences_( BuildingObject* bobj );
		void applyNested_( BuildingObject* bobj );

		WRESULT fixReferencesBy( const std::string& deviceName );


		Tree* buildTree( const std::string& parent, bool children_tree = true ) const;
		void mergeTreeNodeParent_( const BuildingObject* objNode, TreeNode* parentNode ) const;
		void mergeTreeNodeChild_( const BuildingObject* objNode, TreeNode* parentNode ) const;

//@}
	private:
		Response* mmDoReloadBObj( const Request* request );
		Response* mmDoFakeBuildingObjEvent( const Request* request );
		Response* mmDoGetPropertiesOf( const Message* requestMessage );

		Response* mmDoTreeBObj( const Request* request );
		Response* mmDoGetTree( const Request* request );

	protected:
		BusConnector BusBuilding;

		tStrBuildingObjectMap objects;
		tStrLocationMap locations;


}; // class def


/**
 * @class   wosh::BuildingManager_ObjectUpdated
 * @brief   Raised when an object is added or updated.
 *
 * Internally, data is stored as wosh::List. Supports also wosh::Variant type.
 *
 * Fields are:
 *  - \c username [Variant::STRING] (always present, first item of the list)
 *  - \c action type (optional, default: new user)
 *
 * Some getters are provided for convenience:
 * \code

 * \endcode
 *
 * @see     wosh::Fact
 * @see     wosh::UserManager
 ****************************************************************************
 * @version 0.8.399 $Id: BuildingManagerBundle.h 2887 2010-08-11 08:09:41Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
class BuildingManager_ObjectUpdated : public wosh::Fact
 {
	WOSH_SERIALIZABLE(wosh::services::BuildingManager_ObjectUpdated)

	public:
		/**
		 * @brief  Empty constructor.
		 */
		BuildingManager_ObjectUpdated()
			: wosh::Fact(_BuildingManager_EVENT_ObjectUpdated) { }
		/**
		 * @brief  Constructor with initializers.
		 * @param obj_name [in] name of the (updated) user
		 */
		BuildingManager_ObjectUpdated( const std::string& obj_name );
		/**
		 * @brief  Constructor with initializers.
		 * @param obj_name [in] name of the (updated) user
		 * @param obj_action [in] update type: 0=updated; 1=new_user
		 */
		BuildingManager_ObjectUpdated( const std::string& obj_name, short obj_action = 1 );
		/**
		 * @brief  Copy constructor.
		 * @param m [in] the source object to be copied
		 */
		BuildingManager_ObjectUpdated( const BuildingManager_ObjectUpdated& m )
			: wosh::Fact(m) { }
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~BuildingManager_ObjectUpdated() { }

	public:
		/**
		 * @brief   Get name of the (updated) object
		 * @return  obj_name as string
		 */
		std::string getObjectName() const;

		short getObjectAction() const;

		inline bool isObjectUpdated() const			{ return (getObjectAction() == 0); }
		inline bool isObjectNew() const				{ return (getObjectAction() == 1); }
		inline bool isObjectRemoved() const			{ return (getObjectAction() == 2); }

}; // class def


 }; // namespace services
}; // namespace wosh

#endif //__WOSH_Bundles_Services_BuildingManager_H__
